
#include "ckr_spec_AssertableValueCString.h"
#include "ckr_spec_Context.h"

using namespace std;

namespace  ckr
{

//  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


AssertableValueCString::AssertableValueCString(	
							const char*		valueIn,
							const char*		valueNameIn,
							Context&			callerIn,
							int				lineNumberIn,
							const char*		srcFileNameIn )
	: should_be( *this )
	, value( valueIn )
	, caller( callerIn )
	, valueName( valueNameIn )
	, lineNumber( lineNumberIn )
	, srcFileName( srcFileNameIn )
{
}

//  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


void AssertableValueCString::should_equal_impl( const char* other, const char* otherName )
{
	if ( value == NULL && other == NULL )
		return; // no error because they are equal

	else if ( value == NULL || other == NULL 
		|| not( std::string(other) == std::string(value) ) )
	{
		caller.report_failure_operation_cstring( value, valueName, other, otherName, 
			"should equal", lineNumber, srcFileName );
	}
}

void AssertableValueCString::operator==(const char* other)
{
	should_equal_impl(other,"");
}

//  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


void AssertableValueCString::should_not_equal_impl( const char* other, const char* otherName )
{
	if ( (value == NULL && other == NULL) 
		|| value == NULL || other == NULL 
		|| not( std::string(other) != std::string(value) ) )
	{
		caller.report_failure_operation_cstring( value, valueName, other, otherName, 
			"should not equal", lineNumber, srcFileName );
	}
}

void AssertableValueCString::operator!=(const char* other)
{
	should_not_equal_impl(other,"");
}

//  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


void AssertableValueCString::should_be_less_than_impl( const char* other, const char* otherName )
{
	if ( value == NULL || other == NULL
		|| not ( std::string(value) < std::string(other) ) )
	{
		caller.report_failure_operation_cstring( value, valueName, other, otherName, 
			"should be less than", lineNumber, srcFileName );
	}
}

void AssertableValueCString::operator<(const char* other)
{
	should_be_less_than_impl(other,"");
}

//  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

void AssertableValueCString::should_be_less_than_or_equal_to_impl( const char* other, const char* otherName )
{
	if ( value == NULL && other == NULL )
		return; // no error because they are equal

	if ( value == NULL || other == NULL
		|| not ( std::string(value) <= std::string(other) ) )
	{
		caller.report_failure_operation_cstring( value, valueName, other, otherName, 
			"should be less than or equal to", lineNumber, srcFileName );
	}
}

void AssertableValueCString::operator<=(const char* other)
{
	should_be_less_than_or_equal_to_impl(other,"");
}

//  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

void AssertableValueCString::should_be_greater_than_impl( const char* other, 
		const char* otherName )
{
	if ( value == NULL || other == NULL
		|| not ( std::string(value) > std::string(other) ) )
	{
		caller.report_failure_operation_cstring( value, valueName, 
			other, otherName, "should be greater than", 
			lineNumber, srcFileName );
	}
}

void AssertableValueCString::operator>(const char* other)
{
	should_be_greater_than_impl(other,"");
}

//  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

void AssertableValueCString::should_be_greater_than_or_equal_to_impl( 
		const char* other, const char* otherName )
{
	if ( value == NULL && other == NULL )
		return; // no error because they are equal

	if ( value == NULL || other == NULL
		|| not ( std::string(value) >= std::string(other) ) )
	{
		caller.report_failure_operation_cstring( value, valueName, 
			other, otherName, "should be greater than or equal to", 
			lineNumber, srcFileName );
	}
}

void AssertableValueCString::operator>=(const char* other)
{
	should_be_greater_than_or_equal_to_impl(other,"");
}

//  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

void AssertableValueCString::should_be_between_impl( 
						const char*		lowValueIn,
						const char*		lowValueNameIn, 
						const char*		highValueIn,
						const char*		highValueNameIn )
{
	if ( value == NULL || lowValueIn == NULL || highValueIn == NULL
		|| not ( std::string(lowValueIn) < std::string(value) 
			and std::string(value) < std::string(highValueIn) ) )
	{
		caller.report_failure_between_cstring( value, valueName,
				lowValueIn, lowValueNameIn, 
				highValueIn, highValueNameIn,
				lineNumber, srcFileName );
	}
}

//  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

void AssertableValueCString::should_not_be_between_impl( 
						const char*		lowValueIn,
						const char*		lowValueNameIn, 
						const char*		highValueIn,
						const char*		highValueNameIn )
{
	if ( value == NULL || lowValueIn == NULL || highValueIn == NULL
		|| ( std::string(lowValueIn) < std::string(value) 
			and std::string(value) < std::string(highValueIn) ) )
	{
		caller.report_failure_not_between_cstring( 
			value, valueName,
			lowValueIn, lowValueNameIn, 
			highValueIn, highValueNameIn,
			lineNumber, srcFileName );
	}
}

//  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

void AssertableValueCString::should_be_within_impl( 
						const char*		lowValueIn,
						const char*		lowValueNameIn, 
						const char*		highValueIn,
						const char*		highValueNameIn )
{
	if ( value == NULL || lowValueIn == NULL || highValueIn == NULL
		|| not ( std::string(lowValueIn) <= std::string(value) 
			and std::string(value) <= std::string(highValueIn) ) )
	{
		caller.report_failure_within_cstring( value, valueName,
				lowValueIn, lowValueNameIn, 
				highValueIn, highValueNameIn,
				lineNumber, srcFileName );
	}
}

//  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

void AssertableValueCString::should_not_be_within_impl( 
						const char*		lowValueIn,
						const char*		lowValueNameIn, 
						const char*		highValueIn,
						const char*		highValueNameIn )
{
	if ( value == NULL || lowValueIn == NULL || highValueIn == NULL
		|| ( std::string(lowValueIn) <= std::string(value)
			and std::string(value) <= std::string(highValueIn) ) )
	{
		caller.report_failure_not_within_cstring( 
			value, valueName,
			lowValueIn, lowValueNameIn, 
			highValueIn, highValueNameIn,
			lineNumber, srcFileName );
	}
}

//  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

}; // end namespace

